//==================================================================
//  Copyright (C) 2006  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
///
///
///
///
///
//==================================================================

#include <string>
#include "ShadowCastShader.h"

//==================================================================
static const std::string _shaders_header( RENDSHADER_MAKECODE(

	//==================================================================
	struct VSIN_PCTN
	{
		float3	_pos		: POSITION;
	};

	//==================================================================
	struct VSOUT_PTC
	{
		float4	_pos		: POSITION;
		float4	_col		: COLOR0;
		float4	_lpos		: TEXCOORD1;
	};

) );

//==================================================================
static const std::string _vtx_shader_code( RENDSHADER_MAKECODE(

	VSOUT_PTC main(	const VSIN_PCTN			input,
					const uniform float4x4	proj_obj_m,
					const uniform float4x4	view_obj_m,
					const uniform float4x4	lproj_obj_m )
	{
		VSOUT_PTC  output = (VSOUT_PTC)0;

		float4	in_obj_pos4 = float4( input._pos, 1.0 );

		output._pos = mul( proj_obj_m, in_obj_pos4 );
		output._pos.z -= 0.01;
		output._col = float4( 0.1, 0.1, 0.5, 1.0 );

		float4x4	txlproj_obj_m =
							mul( float4x4(
								0.5,	0,		0,		0.5,
								0,		0.5,	0,		0.5,
								0,		0,		0.5,	0.499,
								0,		0,		0,		1 ), lproj_obj_m );

		output._lpos = mul( txlproj_obj_m, in_obj_pos4 );

		return output;
	}
) );

//==================================================================
static const std::string _pix_shader_code( RENDSHADER_MAKECODE(

	//==================================================================
	float4 main( const VSOUT_PTC			input,
				 const uniform sampler2D	depth_tex ) : COLOR
	{
		float4 shadow;

		float tl = min(input._lpos.x, input._lpos.y);
		float bt = max(input._lpos.x, input._lpos.y);

		if ( (0.0 < tl) && (bt < input._lpos.w) )
		{
			shadow.w = 1 - tex2Dproj( depth_tex, input._lpos ).x;
		}
		else
		{
			shadow = 0;
		}

		float4	out_col = shadow;

		return out_col;
	}
) );

//==================================================================
///
//==================================================================
ShadowCastShader::ShadowCastShader( RendDevice *RDevice, RendM5D::Scene *RScenep ) :
	BaseShader( RDevice, RScenep, _shaders_header, _vtx_shader_code, _pix_shader_code )
{
	RendShaderManager	&ShaderManager = _RDevice->_ShaderMng;

	_depth_tex_shparam = GetPixShader()->AddParam( "depth_tex" );
	_lproj_obj_m_shparam = GetVtxShader()->AddParam( "lproj_obj_m" );
}
